#include "./fiipCloud.h"
FormatStruct* fiipCloud_txd = NULL;

static uint8_t* myId = NULL;
static uint8_t* myKey = NULL;
static LinkCfgStruct* link = NULL;
static uint8_t cmd_body[64];
static void* EventEmitter[cloudEventNum];

static uint8_t* cvtCmd(CloudCmdEnum cmd) {
  static uint8_t cmdBuf[2];
  cmdBuf[0] = cmd >> 8;
  cmdBuf[1] = cmd;
  return cmdBuf;
}

void fiipCloud_init(uint8_t* id, uint8_t* key) {
  if (myId == NULL)
    myId = (uint8_t*)mempool_alloc(8);
  mem_cpy(myId, id, 8);
  if (myKey == NULL)
    myKey = (uint8_t*)mempool_alloc(4);
  mem_cpy(myKey, key, 4);
  if (fiipCloud_txd == NULL)
    fiipCloud_txd = format_new();
  if (link == NULL)
    link = route_find(fiip_centerId)->link;
  if (link == NULL)
    WARN("Please connect cloud.");

  fiipCloudVar_init();
  fiipCloud_startListeners();
}
void fiipCloud_on(CloudEventEnum event, void* fun) {
  EventEmitter[event] = fun;
}
void* fiipCloud_getEmitter(CloudEventEnum event) {
  return EventEmitter[event];
}

void fiipCloud_getId(uint8_t* typeId, uint8_t* typeKey) {
  memcpy(&cmd_body[0], typeId, 4);
  memcpy(&cmd_body[4], typeKey, 4);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_getId), 2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 8);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_login() {
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_login), 2);
  format_setVar(fiipCloud_txd, format_field_body, myKey, 4);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_heart() {
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_heart), 2);
  format_setVar(fiipCloud_txd, format_field_body, myKey, 4);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_bind(uint8_t* typeId, uint8_t* code) {
  memcpy(&cmd_body[0], typeId, 4);
  memcpy(&cmd_body[4], code, 4);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_bind), 2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 8);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_unbind(uint8_t* id) {
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_unbind), 2);
  format_setVar(fiipCloud_txd, format_field_body, id, 8);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_enterBinding(uint8_t* code) {
  memcpy(&cmd_body[0], code, 4);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_enterBinding), 2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 4);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_setActualVar(uint8_t* id,
                            uint8_t* key,
                            uint8_t* kVal,
                            uint8_t kLen,
                            uint8_t* vVal,
                            uint8_t vLen) {
  fiipCloudVar_setActual(id, kVal, kLen, vVal, vLen);
  memcpy(&cmd_body[0], id, 8);
  memcpy(&cmd_body[8], key, 4);
  memcpy(&cmd_body[12], &kLen, 1);
  memcpy(&cmd_body[13], kVal, kLen);
  memcpy(&cmd_body[13 + kLen], &vLen, 1);
  memcpy(&cmd_body[14 + kLen], vVal, vLen);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_setActualVar), 2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 14 + kLen + vLen);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_getActualVar(uint8_t* id,
                            uint8_t* key,
                            uint8_t* kVal,
                            uint8_t kLen) {
  memcpy(&cmd_body[0], id, 8);
  memcpy(&cmd_body[8], key, 4);
  memcpy(&cmd_body[12], &kLen, 1);
  memcpy(&cmd_body[13], kVal, kLen);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_getActualVar), 2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 13 + kLen);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_subActualVar(uint8_t* id,
                            uint8_t* key,
                            uint8_t* kVal,
                            uint8_t kLen) {
  memcpy(&cmd_body[0], id, 8);
  memcpy(&cmd_body[8], key, 4);
  memcpy(&cmd_body[12], &kLen, 1);
  memcpy(&cmd_body[13], kVal, kLen);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_subActualVar), 2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 13 + kLen);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_getActualAllVar(uint8_t* id, uint8_t* key) {
  memcpy(&cmd_body[0], id, 8);
  memcpy(&cmd_body[8], key, 4);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_getActualAllVar),
              2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 12);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_subActualAllVar(uint8_t* id, uint8_t* key) {
  memcpy(&cmd_body[0], id, 8);
  memcpy(&cmd_body[8], key, 4);
  cmd_body[12] = 0x00;
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_subActualAllVar),
              2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 13);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}

void fiipCloud_setTargetVar(uint8_t* id,
                            uint8_t* key,
                            uint8_t* kVal,
                            uint8_t kLen,
                            uint8_t* vVal,
                            uint8_t vLen) {
  fiipCloudVar_setTarget(id, kVal, kLen, vVal, vLen);
  memcpy(&cmd_body[0], id, 8);
  memcpy(&cmd_body[8], key, 4);
  memcpy(&cmd_body[12], &kLen, 1);
  memcpy(&cmd_body[13], kVal, kLen);
  memcpy(&cmd_body[13 + kLen], &vLen, 1);
  memcpy(&cmd_body[14 + kLen], vVal, vLen);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_setTargetVar), 2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 14 + kLen + vLen);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_getTargetVar(uint8_t* id,
                            uint8_t* key,
                            uint8_t* kVal,
                            uint8_t kLen) {
  memcpy(&cmd_body[0], id, 8);
  memcpy(&cmd_body[8], key, 4);
  memcpy(&cmd_body[12], &kLen, 1);
  memcpy(&cmd_body[13], kVal, kLen);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_getTargetVar), 2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 1 + kLen);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_subTargetVar(uint8_t* id,
                            uint8_t* key,
                            uint8_t* kVal,
                            uint8_t kLen) {
  memcpy(&cmd_body[0], id, 8);
  memcpy(&cmd_body[8], key, 4);
  memcpy(&cmd_body[12], &kLen, 1);
  memcpy(&cmd_body[13], kVal, kLen);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_subTargetVar), 2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 13 + kLen);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}

void fiipCloud_getTargetAllVar(uint8_t* id, uint8_t* key) {
  memcpy(&cmd_body[0], id, 8);
  memcpy(&cmd_body[8], key, 4);
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_getTargetAllVar),
              2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 12);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
void fiipCloud_subTargetAllVar(uint8_t* id, uint8_t* key) {
  memcpy(&cmd_body[0], id, 8);
  memcpy(&cmd_body[8], key, 4);
  cmd_body[12] = 0x00;
  format_setVar(fiipCloud_txd, format_field_cmd, cvtCmd(cloudCmd_subTargetAllVar),
              2);
  format_setVar(fiipCloud_txd, format_field_body, cmd_body, 13);
  fiip_request(fiipCloud_txd, fiip_centerId, link);
}
